package com.hans.scala.traits

/**
 * @author juntao zhang
 * @since 2015/10/26 13:44
 */
object SelfType extends App {

  trait A {
    def x = 1
  }

  trait B extends A {
    override def x = super.x * 5
  }

  trait C1 extends B {
    override def x = 2
  }

  trait C2 extends A {
    this: B =>
    override def x = 2
  }

  println((new C1 with B).x) // 2
  println((new C2 with B).x) // 10

}

object SelfType2 {

  /**
   * self type trait
   * 责任链模式
   */
  case class User()

  case class Product()

  trait UserRepository {
    def save(user: User)
  }

  trait DatabaseUserRepository extends UserRepository {
    override def save(user: User): Unit = {
      println("save user")
    }
  }

  trait ProductRepository {
    def save(product: Product)
  }

  trait DatabaseProductRepository extends ProductRepository {
    override def save(product: Product): Unit = {
      println("save user")
    }
  }

  trait UserService {
    self: UserRepository =>
    // requires Repository
    def create(user: User) {
      save(user)
    }
  }

  trait ProductService extends UserService with UserRepository {
    self: ProductRepository =>
    // requires Repository
    def create(product: Product) {
      save(product)
    }
  }


  trait ProductService2 extends UserService with DatabaseUserRepository {
    self: ProductRepository =>
    // requires Repository
    def create(product: Product) {
      save(product)
    }
  }

  new ProductService with DatabaseUserRepository with DatabaseProductRepository
  new ProductService2 with DatabaseProductRepository

}